Программирование сетевых приложений

Фундаментальные методы и свойства сетевой архитектуры, механизмы её программной реализации в Desktop/Web-приложениях

Программирование сетевых приложений

Содержание лекции

  • Понятие о сетевой архитектуре
  • Общие представления о процессе передачи данных по сети
  • Понятие протокола и механизмы взаимодействия системы «клиент-сервер»
  • Обзор общих принципов построения многоуровневых приложений
  • Работа с сетью на уровне сокетов и потоков
  • Способы доступа к ресурсам сети из программных приложений при помощи URL
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Понятие о сетевой архитектуре

Определение

Сетевая архитектура - это совокупность принципов, протоколов и технологий, определяющих организацию взаимодействия между компонентами распределённой системы.

Основные характеристики:

  • Топология - физическая и логическая структура сети
  • Протоколы - правила обмена данными
  • Масштабируемость - способность к росту
  • Надёжность - устойчивость к сбоям
  • Производительность - скорость передачи данных
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Модели сетевой архитектуры

Модель OSI (7 уровней)

  1. Физический - электрические сигналы
  2. Канальный - доступ к среде передачи
  3. Сетевой - маршрутизация
  4. Транспортный - надёжная передача
  5. Сеансовый - управление соединениями
  6. Представления - формат данных
  7. Прикладной - интерфейс приложений

Модель TCP/IP (4 уровня)

  • Сетевой доступа, Интернет, Транспортный, Прикладной
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Процесс передачи данных по сети

Этапы передачи:

  1. Инициализация соединения
  2. Фрагментация данных
  3. Упаковка в пакеты
  4. Адресация и маршрутизация
  5. Передача по физическому каналу
  6. Приём и сборка пакетов
  7. Подтверждение доставки

Ключевые понятия:

  • Пакет - единица передачи данных
  • Заголовок - служебная информация
  • Полезная нагрузка - пользовательские данные
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Понятие сетевого протокола

Определение

Сетевой протокол - это формальный набор правил и соглашений, определяющих формат, порядок и методы передачи данных между участниками сетевого взаимодействия.

Характеристики протоколов:

  • Синтаксис - структура данных
  • Семантика - значение полей
  • Временные характеристики - порядок обмена
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Классификация протоколов

По уровням модели OSI:

  • Прикладные: HTTP, FTP, SMTP, DNS
  • Транспортные: TCP, UDP
  • Сетевые: IP, ICMP, ARP
  • Канальные: Ethernet, Wi-Fi

По назначению:

  • Протоколы передачи данных: TCP, UDP
  • Протоколы маршрутизации: IP, OSPF
  • Протоколы прикладного уровня: HTTP, FTP, SMTP
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Механизмы взаимодействия клиент-сервер

Основная схема:

Клиент → Запрос → Сервер
Клиент ← Ответ ← Сервер

Типы архитектур:

  1. Одноранговая (P2P) - равные участники
  2. Клиент-сервер - централизованное управление
  3. Гибридная - комбинированная модель
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Принципы клиент-серверной архитектуры

Роли участников:

  • Клиент - инициатор запросов
  • Сервер - обработчик запросов

Особенности:

  • Асимметричность - разные функции клиента и сервера
  • Масштабируемость - возможность добавления клиентов
  • Централизация - управление ресурсами на сервере
  • Безопасность - защита данных на сервере
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Пример HTTP-запроса и ответа

Запрос клиента:

GET /index.html HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0
Accept: text/html

Ответ сервера:

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1234

<html>
<body>
<h1>Hello, World!</h1>
</body>
</html>
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Многоуровневая архитектура приложений

Трёхуровневая архитектура:

  1. Представления (Presentation Tier)

    • Пользовательский интерфейс
    • Обработка ввода/вывода
  2. Бизнес-логика (Business Logic Tier)

    • Обработка данных
    • Принятие решений
  3. Данных (Data Access Tier)

    • Хранение информации
    • Доступ к базе данных
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Преимущества многоуровневой архитектуры

Модульность:

  • Разделение ответственности
  • Независимая разработка уровней

Масштабируемость:

  • Горизонтальное масштабирование
  • Балансировка нагрузки

Поддержка:

  • Локализация изменений
  • Повторное использование компонентов

Безопасность:

  • Защита на каждом уровне
  • Контроль доступа
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Сокеты (Sockets) - основа сетевого программирования

Определение

Сокет - это программный интерфейс для организации сетевого взаимодействия между процессами, предоставляющий механизм для передачи данных по сети.

Типы сокетов:

  • TCP-сокеты - надёжная передача (SOCK_STREAM)
  • UDP-сокеты - без установления соединения (SOCK_DGRAM)
  • Raw-сокеты - доступ к низкоуровневым протоколам
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Создание TCP-сокета в C++

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

int createServerSocket(int port) {
    // Создание сокета
    int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (serverSocket == -1) {
        return -1;
    }
    
    // Настройка адреса
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(port);
    serverAddr.sin_addr.s_addr = INADDR_ANY;
    
    // Привязка сокета к адресу
    if (bind(serverSocket, (struct sockaddr*)&serverAddr, 
             sizeof(serverAddr)) < 0) {
        close(serverSocket);
        return -1;
    }
    
    // Ожидание подключений
    listen(serverSocket, 5);
    return serverSocket;
}
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

TCP-клиент

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string>

int createClientSocket(const std::string& serverIP, int port) {
    // Создание сокета
    int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (clientSocket == -1) {
        return -1;
    }
    
    // Настройка адреса сервера
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(port);
    serverAddr.sin_addr.s_addr = inet_addr(serverIP.c_str());
    
    // Подключение к серверу
    if (connect(clientSocket, (struct sockaddr*)&serverAddr, 
                sizeof(serverAddr)) < 0) {
        close(clientSocket);
        return -1;
    }
    
    return clientSocket;
}

void sendMessage(int socket, const std::string& message) {
    send(socket, message.c_str(), message.length(), 0);
}
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Работа с UDP-сокетами

#include <sys/socket.h>
#include <netinet/in.h>

int createUDPSocket() {
    return socket(AF_INET, SOCK_DGRAM, 0);
}

void sendUDPMessage(int socket, const std::string& message, 
                   const std::string& serverIP, int port) {
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(port);
    serverAddr.sin_addr.s_addr = inet_addr(serverIP.c_str());
    
    sendto(socket, message.c_str(), message.length(), 0,
           (struct sockaddr*)&serverAddr, sizeof(serverAddr));
}

std::string receiveUDPMessage(int socket) {
    char buffer[1024] = {0};
    sockaddr_in clientAddr;
    socklen_t clientLen = sizeof(clientAddr);
    
    int bytesReceived = recvfrom(socket, buffer, 1024, 0,
			(struct sockaddr*)&clientAddr, 
			&clientLen);
    
    if (bytesReceived > 0) {
        return std::string(buffer, bytesReceived);
    }
    
    return "";
}
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Доступ к ресурсам сети при помощи URL

Структура URL

scheme://host:port/path?query#fragment
https://example.com:8080/api/users?id=1&active=true#results
Компонент Описание Пример
scheme Протокол доступа https, ftp, ws
host Имя хоста или IP-адрес example.com, 192.168.1.1
port Номер порта (опционально) 8080
path Путь к ресурсу /api/users
query Параметры запроса id=1&active=true
fragment Якорь внутри документа results
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

URL в Qt — класс QUrl

#include <QUrl>
#include <QUrlQuery>

QUrl url("https://example.com:8080/api/users?id=1");

// Разбор компонентов
url.scheme();      // "https"
url.host();        // "example.com"
url.port();        // 8080
url.path();        // "/api/users"
url.query();       // "id=1"

// Построение URL с параметрами
QUrl apiUrl;
apiUrl.setScheme("https");
apiUrl.setHost("api.example.com");
apiUrl.setPath("/v1/data");

QUrlQuery query;
query.addQueryItem("format", "json");
query.addQueryItem("limit", "100");
apiUrl.setQuery(query);
// Результат: https://api.example.com/v1/data?format=json&limit=100
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

HTTP-запрос по URL в Qt

#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QUrl>
#include <QJsonDocument>

void fetchJsonData() {
    QNetworkAccessManager* manager = new QNetworkAccessManager();
    
    QUrl url("https://api.example.com/users");
    QNetworkRequest request(url);
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    
    QNetworkReply* reply = manager->get(request);
    
    QObject::connect(reply, &QNetworkReply::finished, [=]() {
        if (reply->error() == QNetworkReply::NoError) {
            QByteArray data = reply->readAll();
            QJsonDocument doc = QJsonDocument::fromJson(data);
            // Обработка JSON-ответа...
        } else {
            qDebug() << "Error:" << reply->errorString();
        }
        reply->deleteLater();
    });
}
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Безопасность в сетевом программировании

Основные угрозы:

  • Перехват данных - шифрование
  • Подмена данных - цифровые подписи
  • Отказ в обслуживании - ограничение ресурсов
  • Несанкционированный доступ - аутентификация
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Производительность сетевых приложений

Оптимизация:

  1. Буферизация - накопление данных перед отправкой
  2. Сжатие - уменьшение объёма передаваемых данных
  3. Многопоточность - параллельная обработка
  4. Кэширование - хранение часто запрашиваемых данных
  5. Пул соединений - повторное использование соединений
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Современные тенденции в сетевой архитектуре

Микросервисы:

  • Разделение приложения на независимые сервисы
  • Лёгкое масштабирование отдельных компонентов
  • Независимая разработка и развёртывание

Контейнеризация:

  • Docker и Kubernetes для управления сервисами
  • Изоляция и переносимость приложений
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Облачные технологии:

  • AWS, Azure, Google Cloud Platform
  • Автоматическое масштабирование
  • Глобальное распределение

Протоколы нового поколения:

  • HTTP/2 и HTTP/3 для веб-приложений
  • WebSocket для двунаправленной связи
  • gRPC для высокопроизводительных сервисов
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Заключение

Ключевые принципы сетевой архитектуры:

  1. Модульность - разделение на независимые компоненты
  2. Масштабируемость - способность к росту
  3. Надёжность - устойчивость к сбоям
  4. Безопасность - защита данных и ресурсов
  5. Производительность - эффективное использование ресурсов
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Перспективы развития:

  • Интернет вещей (IoT)
  • 5G и новые протоколы
  • Искусственный интеллект в сетевых системах
  • Квантовые коммуникации
Фундаментальные методы и свойства сетевой архитектуры
Программирование сетевых приложений

Вопросы для самопроверки

  1. Какие уровни включает модель OSI и как они соотносятся с TCP/IP?
  2. В чём различие между TCP и UDP протоколами?
  3. Какие преимущества даёт многоуровневая архитектура приложений?
  4. Как реализуется клиент-серверное взаимодействие на уровне сокетов?
  5. Какие методы оптимизации производительности сетевых приложений вы знаете?
  6. Что такое URL и какие компоненты он содержит?
  7. Какие существуют угрозы безопасности в сетевом программировании?
  8. В чём преимущества асинхронной обработки сетевых запросов?
Фундаментальные методы и свойства сетевой архитектуры

Заметки докладчика: - Это вторая вводная лекция. Переход от ООП к сетевым концепциям. - Студентам, изучавшим «Компьютерные сети», часть теории (OSI, TCP/IP) будет знакома — можно пройти быстрее. - Основной акцент в этой лекции: связь теории с практикой программирования (сокеты, клиент-сервер). - Примеры сокетов в этой лекции — на POSIX C API. В лекциях 9 и 12 будут Qt-аналоги.

Заметки докладчика: - Аналогия OSI: отправка письма (конверт = заголовки каждого уровня). - OSI — теоретическая модель, TCP/IP — практическая. На практике используется TCP/IP. - Для программиста-сетевика наиболее важны уровни: Транспортный (TCP/UDP) и Прикладной (HTTP, DNS). - В рамках курса мы будем работать преимущественно на транспортном (сокеты) и прикладном (HTTP, RPC) уровнях. - Мнемоника для OSI (снизу вверх): Физический, Канальный, Сетевой, Транспортный, Сеансовый, Представления, Прикладной.

Заметки докладчика: - Пример для пояснения: HTTP-запрос — синтаксис определяет формат (GET /path HTTP/1.1), семантика — что означает каждый заголовок, временные характеристики — кто первый отправляет, каков таймаут ответа. - В рамках курса будут рассмотрены: TCP, UDP, HTTP (и JSON-RPC/XML-RPC поверх HTTP). - Полезно упомянуть RFC — документы, описывающие протоколы (RFC 793 для TCP, RFC 768 для UDP).

Заметки докладчика: - Сокеты — это АПИ, появившееся в BSD Unix (1983). Winsock — реализация для Windows. - Аналогия: сокет = розетка (socket), через которую процесс «подключается» к сети. - TCP-сокет: аналог телефонного звонка (установили соединение — говорим — положили трубку). - UDP-сокет: аналог отправки письма (отправили — надеемся, что дойдёт). - В Qt: QTcpSocket, QUdpSocket — высокоуровневая обёртка над системными сокетами (лекция 9).

Заметки докладчика: - Обратить внимание на порядок: socket() → bind() → listen() — это стандартная последовательность для TCP-сервера. - htons() — преобразует порядок байтов хоста в сетевой (big-endian). Необходимо, т.к. форматы могут различаться. - INADDR_ANY — сервер слушает на всех интерфейсах. Для привязки к конкретному IP использовать inet_addr(). - listen(serverSocket, 5) — 5 — размер очереди ожидающих подключений (backlog). - Этот пример POSIX C — для Windows нужны WSAStartup/closesocket (см. дополнительную лекцию по сокетам).

Заметки докладчика: - URL — это стандартизированный способ адресации ресурсов в сети (RFC 3986). - QUrl — основной класс Qt для работы с URL. Он выполняет валидацию и нормализацию. - QNetworkAccessManager — высокоуровневый класс для HTTP/FTP запросов (подробно в лекции 9). - QUrlQuery удобен для построения query-строки — автоматически кодирует спецсимволы. - Загрузка файла по URL — частая задача в сетевых приложениях (обновления, конфигурация, медиа).

Заметки докладчика: Ожидаемые ответы: 1. OSI: физический, канальный, сетевой, транспортный, сеансовый, представления, прикладной. TCP/IP: сетевой доступа, интернет, транспортный, прикладной. OSI 7→4 уровней, сеансовый+представления объединены. 2. TCP — надёжный, с установлением соединения, гарантия доставки, порядок. UDP — быстрый, без соединения, нет гарантии доставки. 3. Разделение ответственности, независимая разработка/масштабирование уровней, замена компонентов. 4. Клиент: socket→connect→send/recv. Сервер: socket→bind→listen→accept→send/recv. 5. Буферизация, сжатие, многопоточность, кэширование, пул соединений. 6. URL = scheme://host:port/path?query#fragment. Пример: https://example.com:8080/api/users?id=1. 7. Перехват (MITM), подмена, DoS, несанкционированный доступ, инъекции. 8. Не блокирует основной поток, параллельная обработка, лучшая отзывчивость UI.